<script setup>

import MyNav from "../../../components/MyNav.vue";
import MyHead from "../../../components/MyHead.vue";
import {onMounted, reactive, ref} from "vue";
import {
  dateFormat,
  genderFormat,
  hasNull,
  isNotNull,
  studentStatusFormat,
} from "../../../util/index.js";
import {getResponseData} from "../../../request/index.js";
import {deleteApi, deleteBatchApi, excelApi, listApi, pageApi} from "../../../api/axios.js";
import MyTable from "../../../components/MyTable.vue";
import {ElMessage} from "element-plus";
import {PROJECT_INFO, STUDENT_STATUS_TAG_OPTIONS} from "../../../const/index.js";


// 表格数据 + 分页数据 + 学生编号 + 真实姓名
let records = ref();
let pageInfo = reactive({pageNum: 1, pageSize: 10, total: 0, callback: page});
let studentNumber = ref();
let studentRealname = ref();
let fkSchoolId = ref();
let fkClubId = ref();
let fkSalesmanId = ref();
let status = ref();

// 学校下拉菜单
let schoolOptions = ref([]);
// 班级下拉菜单
let clubOptions = ref([]);
// 负责销售下拉菜单
let salesmanOptions = ref([]);

// 路径导航
const navItems = [
  {icon: 'Platform', label: '班级管理'},
  {icon: 'Avatar', label: '学员列表'},
];

// 数据头
const headItems = [
  {type: 'ipt', span: 4, placeholder: '搜索学生编号', callback: pageByNumber},
  {type: 'ipt', span: 4, placeholder: '搜索真实姓名', callback: pageByRealname},
  {type: 'opt', span: 4, placeholder: '搜索所在学校', callback: pageBySchoolId, options: schoolOptions.value},
  {type: 'opt', span: 4, placeholder: '搜索所在班级', callback: pageByClubId, options: clubOptions.value},
  {type: 'opt', span: 4, placeholder: '搜索负责销售', callback: pageBySalesmanId, options: salesmanOptions.value},
  {type: 'opt', span: 4, placeholder: '搜索学生状态', callback: pageByStatus, options: STUDENT_STATUS_TAG_OPTIONS},
];


// 表格列
const columns = [
  {label: '状态', prop: 'status', type: 'tag', tagTypeFn: studentStatusTagTypeFn, format: studentStatusFormat},
  {label: '学生头像', prop: 'avatar', minio: minio, type: 'img'},
  {label: '学生编号', prop: 'number'},
  {label: '学生姓名', prop: 'realname'},
  {label: '所在学校', prop: 'school', format: schoolFullTitleFormat, width: 300},
  {label: '所在班级', prop: 'club.title'},
  {label: '学生性别', prop: 'gender', type: 'tag', tagTypeFn: studentGenderTagTypeFn, format: genderFormat},
  {label: '学生描述', prop: 'info', type: 'card', tooltip: false},
  {label: '手机号码', prop: 'phone'},
  {label: '微信号码', prop: 'wechat'},
  {label: '年龄', prop: 'age'},
  {label: '所在省份', prop: 'province'},
  {label: '现居住地', prop: 'address'},
  {label: '负责销售', prop: 'salesman.realname'},
  {label: '身份证号', prop: 'idcard'},
  {label: '入学日期', prop: 'studyDate', format: dateFormat},
  {label: '急联姓名', prop: 'emergencyName'},
  {label: '急联电话', prop: 'emergencyPhone'},
];

/* =================================== 学生状态处理 ===================================== */

// 根据学生状态返回标签颜色
function studentStatusTagTypeFn(e) {
  if (e === 0) return 'success';
  if (e === 1) return 'primary';
  if (e === 2) return 'warning';
  if (e === 3) return 'danger';
  return 'default';
}

/* =================================== 学校处理 ===================================== */

function schoolFullTitleFormat(school) {
  return school['title'] + '-' + school['college'] + '-' + school['major'] + '-' + school['clazz'];
}

/* =================================== 学生性别处理 ===================================== */

// 根据学生性别返回标签颜色
function studentGenderTagTypeFn(e) {
  if (e === 0) return 'danger';
  if (e === 1) return 'primary';
  return 'default';
}

/* =================================== 学生头像 ===================================== */

function minio(src) {
  return PROJECT_INFO.minioHost + '/avatar/' + src;
}

/* =================================== 搜索学生编号 ===================================== */

function pageByNumber(val) {
  // 仅当输入框有值，或者当前处于按条件分页状态时，发送分页请求
  if (val || studentNumber.value) {
    studentNumber.value = val;
    page();
  }
}

/* =================================== 搜索真实姓名 ===================================== */

function pageByRealname(val) {
  // 仅当输入框有值，或者当前处于按条件分页状态时，发送分页请求
  if (val || studentRealname.value) {
    studentRealname.value = val;
    page();
  }
}

/* =================================== 搜索所在学校 ===================================== */

function pageBySchoolId(val) {
  // 仅当输入框有值，或者当前处于按条件分页状态时，发送分页请求
  if (val || fkSchoolId.value) {
    fkSchoolId.value = val;
    page();
  }
}

/* =================================== 搜索所在班级 ===================================== */

function pageByClubId(val) {
  // 仅当输入框有值，或者当前处于按条件分页状态时，发送分页请求
  if (val || fkClubId.value) {
    fkClubId.value = val;
    page();
  }
}

/* =================================== 搜索负责销售 ===================================== */

function pageBySalesmanId(val) {
  // 仅当输入框有值，或者当前处于按条件分页状态时，发送分页请求
  if (val || fkSalesmanId.value) {
    fkSalesmanId.value = val;
    page();
  }
}

/* =================================== 搜索学生状态 ===================================== */

function pageByStatus(val) {
  // 若状态为0，则转换为字符串'0'，因为JS视0为false
  if (val === 0) val = '0';
  // 仅当输入框有值，或者当前处于按条件分页状态时，发送分页请求
  if (val || status.value) {
    status.value = val;
    page();
  }
}

async function page(pageNum = pageInfo['pageNum'], pageSize = pageInfo['pageSize']) {
  let config = {
    api: pageApi,
    args: {module: 'student'},
    params: {pageNum, pageSize},
    records: records,
    pageInfo: pageInfo
  }

  // 若学生编号不为空，则使用学生编号作为分页条件
  if (studentNumber.value) {
    config['params']['number'] = studentNumber.value;
  }

  // 若真实姓名不为空，则使用真实姓名作为分页条件
  if (studentRealname.value) {
    config['params']['realname'] = studentRealname.value;
  }

  // 若所在学校不为空，则使用所在学校作为分页条件
  if (fkSchoolId.value) {
    config['params']['fkSchoolId'] = fkSchoolId.value;
  }

  // 若所在班级不为空，则使用所在班级作为分页条件
  if (fkClubId.value) {
    config['params']['fkClubId'] = fkClubId.value;
  }

  // 若负责销售不为空，则使用负责销售作为分页条件
  if (fkSalesmanId.value) {
    config['params']['fkSalesmanId'] = fkSalesmanId.value;
  }

  // 若学生状态不为空，则使用学生状态作为分页条件
  if (status.value) {
    config['params']['status'] = status.value;
  }

  // 发送分页请求
  await myPage(config);
}

async function myPage(config) {
  // 必传参数
  const api = config['api'];
  const records = config['records'];
  const pageInfo = config['pageInfo'];
  const params = config['params'];
  // 空值保护
  if (hasNull(api, params, records, pageInfo)) return;
  // 可选参数
  const args = config['args'];
  // 发送请求
  let res = isNotNull(args) ? await api(params, args) : await api (params);
  let data = getResponseData(res);
  if (isNotNull(data)) {
    records.value = data['list'] || data['records'];
    pageInfo['pageNum'] = data['pageNum'] || data['pageNumber'];
    pageInfo['pageSize'] = data['pageSize'] || data['size'];
    pageInfo['total'] = data['total'] || data['totalRow'];
  }
}

/* =================================== 删除成功回调 ===================================== */

function deleteSuccess() {
  ElMessage.success('删除成功');
  page();
}

/* =================================== 报表打印 ===================================== */

function downloadExcel() {
  excelApi('/student/excel', '学生报表');
}

/* =================================== 加载函数 ===================================== */

onMounted(async () => {
  await page();

  // 查询所有学校，并添加到下拉菜单里面去
  Object.values(getResponseData(await listApi({module: 'school'}))).forEach(school => {
    schoolOptions.value.push({label: school['title'], value: school['id']});
  });

  // 查询所有班级，并添加到下拉菜单里面去
  Object.values(getResponseData(await listApi({module: 'club'}))).forEach(club => {
    clubOptions.value.push({label: club['title'], value: club['id']});
  });

  // 查询所有负责销售，并添加到下拉菜单里面去
  Object.values(getResponseData(await listApi({module: 'emp'}))).forEach(emp => {
    salesmanOptions.value.push({label: emp['realname'], value: emp['id']});
  });

});
</script>

<template>
  <my-nav :items="navItems"/>
  <my-head :items="headItems"/>
  <my-table module="student"
            insert-page="/StudentInsert"
            update-page="/StudentUpdate"
            :records="records"
            :columns="columns"
            :delete-api="deleteApi"
            :delete-batch-api="deleteBatchApi"
            :delete-callback="deleteSuccess"
            :excel-api="downloadExcel"
            :page-info="pageInfo"/>
</template>

<style scoped lang="scss">

</style>